using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Pavilion
{
    public delegate void MouseObjectHandler(object sender, MouseCursor mouseCursor);

    abstract public class MouseCursor
    {
        #region //////////////////////////////////////////////Attributes//////////////////////////////////////////////

        protected Vector2 position;
        private float leftBound, rightBound, upperBound, lowerBound;
        protected int scrollWheelValue, scrollWheelRange;

        public event Action<MouseCursor> MouseMoved, LeftMousePressed, LeftMouseReleased, RightButtonPressed, RightButtonReleased, ScrollWheelChanged;

        #endregion

        #region ////////////////////////////////////////////Initialization////////////////////////////////////////////

        public MouseCursor()
        {
            position = new Vector2();
        }

        public Delegate[] GetInvocationList()
        {
            return LeftMousePressed.GetInvocationList();
        }

        public void Initialize(float scale, int leftBound, int rightBound, int upperBound, int lowerBound)
        {
            this.leftBound = leftBound * scale;
            this.rightBound = rightBound * scale;
            this.upperBound = upperBound * scale;
            this.lowerBound = lowerBound * scale;
        }

        #endregion

        #region ////////////////////////////////////////////////Methods///////////////////////////////////////////////

        public bool checkBounds(Rectangle Bounds)
        {
            return Position.X < Bounds.Right && Position.X > Bounds.Left &&
                Position.Y < Bounds.Bottom && Position.Y > Bounds.Top;
        }

        abstract public void Update(GameTime gameTime);

        #endregion

        #region ////////////////////////////////////////////Gets and Sets/////////////////////////////////////////////

        public List<Delegate> LeftMousePressedInvocationList
        {
            get
            {
                if (LeftMousePressed == null)
                    return new List<Delegate>();
                else
                    return new List<Delegate>(LeftMousePressed.GetInvocationList());
            }
        }

        public List<Delegate> LeftMouseReleasedInvocationList
        {
            get
            {
                if (LeftMouseReleased == null)
                    return new List<Delegate>();
                else
                    return new List<Delegate>(LeftMouseReleased.GetInvocationList());
            }
        }

        /// <summary>
        /// Gets the position of the mouse cursor.
        /// </summary>
        public Vector2 Position
        {
            get { return position; }
        }

        public virtual void setPosition(float xPos, float yPos)
        {
            this.position.X = xPos;
            this.position.Y = yPos;
        }

        /// <summary>
        /// Gets the amount the scroll wheel has be spun in the last cycle.
        /// </summary>
        public int ScrollWheelRange
        {
            get { return scrollWheelRange; }
        }

        #endregion

        #region ////////////////////////////////////////////////Events////////////////////////////////////////////////

        protected void OnMouseMoved()
        {
            if (MouseMoved != null)
                MouseMoved(this);
        }

        protected void OnScrollWheelChanged()
        {
            if (ScrollWheelChanged != null)
                ScrollWheelChanged(this);
        }

        protected void OnLeftButtonPressed()
        {
            if (LeftMousePressed != null)
                LeftMousePressed(this);
        }

        protected void OnLeftButtonReleased()
        {
            if (LeftMouseReleased != null)
                LeftMouseReleased(this);
        }

        protected void OnRightButtonPressed()
        {
            if (RightButtonPressed != null)
                RightButtonPressed(this);
        }

        protected void OnRightButtonReleased()
        {
            if (RightButtonReleased != null)
                RightButtonReleased(this);
        }

        #endregion
    }
}
